package muilty_thread.java_current_practice_and_kernel.cp8;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ThreadMonitorDemo {
    volatile boolean inited = false;
    static int threadIndex = 0;
    final BlockingQueue<String> channel = new ArrayBlockingQueue<String>(100);

    public static void main(String[] args) throws InterruptedException {
        ThreadMonitorDemo ts = new ThreadMonitorDemo();
        ts.init();
        for (int i = 0; i < 100; i++) {
            ts.service("test-"+i);
        }

    }

    public synchronized void init(){
        if (inited) {
            return;
        }
        WorkThread wt = new WorkThread();
        wt.setName("worker-" + threadIndex++);
        wt.setUncaughtExceptionHandler(new ThreadMonitor());
        wt.start();
        inited = true;
    }

    public void service(String msg) throws InterruptedException {
        channel.put(msg);
    }
    private void process(){
        if ((int) Math.random() * 100 < 2) {
            throw new RuntimeException();
        }
    }

    private class ThreadMonitor implements Thread.UncaughtExceptionHandler{
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println(t.getName());
            System.out.println(e);
            inited = false;
            init();
        }
    }
    private class WorkThread extends Thread{

        @Override
        public void run() {
            while (true) {
                try {
                    String take = channel.take();
                    System.out.println(take);
                    process();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }



}
